Skip to content

feat(core): info/success/warning/danger variants on json-render Card & Stack - #491

Open
dvcolomban wants to merge 1 commit into
vitejs:mainfrom
dvcolomban:feat/json-render-semantic-variants
Open

feat(core): info/success/warning/danger variants on json-render Card & Stack#491
dvcolomban wants to merge 1 commit into
vitejs:mainfrom
dvcolomban:feat/json-render-semantic-variants

Conversation

@dvcolomban

@dvcolomban dvcolomban commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Continues #477's variant/interactive work on Card/Stack with the four semantic hues already used by Badge (info/success/warning/danger):

  • Added a shared variantSurface(variant) helper in tokens.ts so Card and Stack read one table instead of duplicating a variantBackground map each.
  • Semantic variants get their own lighter tints, independent from Badge's pill palette (colors) — a badge-strength fill would read as a heavy block over a whole card, so body/header/border/hover alphas are tuned separately.
  • Card's header bar reads a step stronger than its body, so a titled card is a two-tone surface rather than one flat tint.
  • Borders are now variant-tinted instead of staying neutral grey, and interactive hover strengthens the variant's own border color (not a generic grey) — previously the hover step was indistinguishable from rest for the semantic variants.
  • primary/secondary/ghost/danger remain pixel-identical to today's look — this is additive.
  • Stack's row variant is independent from its parent Card's variant, and the Card story now has a rowVariant Control so both can be exercised separately.

Screenshots

01-info 02-success 03-warning 04-success-interactive-hover 05-danger-legacy-unchanged 06-warning-rebalanced 07-danger-now-tinted-border

Test plan

  • pnpm run lint
  • pnpm run typecheck
  • Storybook Card story Controls: cycled all 7 variants × interactive × rowVariant, confirmed primary/secondary/ghost/danger are unchanged from upstream/main, confirmed hover border is a clearly visible step up from rest for the four semantic variants

@pkg-pr-new

pkg-pr-new Bot commented Jul 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

@vitejs/devtools

npm i https://pkg.pr.new/@vitejs/devtools@491

@vitejs/devtools-kit

npm i https://pkg.pr.new/@vitejs/devtools-kit@491

@vitejs/devtools-oxc

npm i https://pkg.pr.new/@vitejs/devtools-oxc@491

@vitejs/devtools-rolldown

npm i https://pkg.pr.new/@vitejs/devtools-rolldown@491

@vitejs/devtools-vite

npm i https://pkg.pr.new/@vitejs/devtools-vite@491

@vitejs/devtools-vitest

npm i https://pkg.pr.new/@vitejs/devtools-vitest@491

commit: 94d0bed

@dvcolomban
dvcolomban force-pushed the feat/json-render-semantic-variants branch 2 times, most recently from 10cff95 to 0471912 Compare July 28, 2026 17:14
@dvcolomban
dvcolomban marked this pull request as ready for review July 28, 2026 17:21
@antfu

antfu commented Jul 31, 2026

Copy link
Copy Markdown
Member

Would you explain a bit why you want colored variants on cards and stacks? I don't feel it's a common ui practice tho

@dvcolomban

Copy link
Copy Markdown
Contributor Author

Hello,

Our immediate need comes from a microfrontend testing panel where developers can override shells, package versions, and import-map entries. The panel can contain dozens of dense rows with package names, URLs, versions, actions, and statuses.

We currently represent state with pills, but those pills are easy to lose among the surrounding metadata. This is especially problematic for active or invalid overrides: a developer may otherwise test or debug the application without noticing that the environment has been modified.

A subtle Stack tint lets us surface the state at the scope where it applies—the whole row—while keeping the pill or text as the precise, non-color-only indicator. Similarly, a Card tint can communicate that a whole section contains an active override, warning, or error.

Beyond our specific panel, these variants could be useful to other information-dense DevTools views where important state competes with a lot of technical metadata: test results, diagnostics, requests, plugins, configuration entries, or dependency inspectors.

Cards also have a separate contextual use. A panel may need to render an informational note, warning, success result, or error explanation alongside its main content. Semantic card variants provide a consistent way to express that context without each JSON-render consumer implementing its own alert-like surface.

The intention isn't to make cards generally colorful. The variants are opt-in, use restrained surface tints rather than badge-strength fills, and preserve the existing default appearance. They provide additional emphasis when a badge is too local or when the semantic context applies to an entire row or section.

We also heavily use tinted info and warning/danger card in our internal documentation tooling and plan on migrating it to a devtool dock panel to co-locate it with the dev environement.

For illustration, here a work in progress dock where the information density makes it hard to detect state changes:

image

…& Stack

Extends the variant model from vitejs#477 (which added secondary/ghost/danger)
with info/success/warning — new variants entirely, with no prior pixel
output to preserve. Also retunes danger: vitejs#477 gave it a flat colored
background with a plain grey border, which reads as a mismatch once
info/success/warning exist alongside it with a real tinted border, so
danger now gets the same treatment as the three new variants instead of
staying a fourth "neutral" surface.

Each of the four semantic variants (info/success/warning/danger) gets:
- a light background tint on the body (Card content, Stack row)
- a stronger same-hue tint on Card's header bar, so a titled card reads as
  a deliberate two-tone surface rather than one flat wash
- a matching border, brightened on hover when `interactive`

primary/secondary/ghost keep their exact prior background, border (none),
and hover behavior — verified via the Card story's Controls panel.

Also types Card's and Stack's own props (`CardProps`, `StackProps`)
co-located in their component files, and adds `registryProps<Type, Props>()`
— a typed alternative to the untyped `props: ['element', 'emit', ...]`
array form every registry component currently uses, so `defineComponent`
infers `setup`'s `ctx.element.props` as the component's own type instead of
`Record<string, any>`. Both types are re-exported from the client
webcomponents entry (`@vitejs/devtools/client/webcomponents`, already
public) as opt-in strict types.
@dvcolomban
dvcolomban force-pushed the feat/json-render-semantic-variants branch from 8c5d315 to 94d0bed Compare July 31, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants